﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RefactorThis.GraphDiff.Attributes;
using TanmiaGrp.Basis.Core;

namespace TanmiaGrp.GeneralLedger.Core
{
    public class JournalEntry : BusinessObject
    {
        #region Private Fields
        private int journalEntryID;
        private double credit;
        private double debit;
        private string description;
        private Account account;
        #endregion Private Fields

        #region Keys

        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int JournalEntryID
        {
            get { return journalEntryID; }
            set
            {
                if (journalEntryID != value)
                {
                    journalEntryID = value;
                    RaisePropertyChanged(() => JournalEntryID);
                }
            }
        }

        [Required]
        [ForeignKey("AccountID"), Column(Order = 2)]
        [Associated]
        public Account Account
        {
            get { return account; }
            set
            {
                if (account != value)
                {
                    account = value;
                    RaisePropertyChanged(() => Account);
                }
            }
        }

        public int AccountID { get; set; }

        [ForeignKey("JournalID"), Column(Order = 1)]
        public Journal Journal { get; set; }

        public int JournalID { get; set; }

        #endregion

        [Required, Range(0, double.MaxValue)]
        public double Debit
        {
            get { return debit; }
            set
            {
                if (debit != value)
                {
                    debit = value;
                    RaisePropertyChanged(() => Debit);
                }
            }
        }

        [Required, Range(0, double.MaxValue)]
        public double Credit
        {
            get { return credit; }
            set
            {
                if (credit != value)
                {
                    credit = value;
                    RaisePropertyChanged(() => Credit);
                }
            }
        }

        [Required, MaxLength(255)]
        public string Description
        {
            get { return description; }
            set
            {
                if (description != value)
                {
                    description = value;
                    RaisePropertyChanged(() => Description);
                }
            }
        }

        public JournalEntry()
        {
            CreateDate = DateTime.Now;
        }

        #region Overriden Members

        public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            if (Credit > 0 && Debit > 0)
                yield return new ValidationResult("لا يمكن لطرفي القيد أن يكونا أكبر من الصفر.", new string[] { "Credit", "Debit" });

            foreach (var item in base.Validate(validationContext))
                yield return item;
        }

        public override bool Equals(object obj)
        {
            JournalEntry entry = obj as JournalEntry;

            if (entry == this) return true;

            if (entry == null) return false;

            if (!base.Equals(obj)) return false;

            if (!entry.JournalEntryID.Equals(JournalEntryID)) return false;

            return true;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
        #endregion

        #region Mapping

        public VoucherDetail ToPostVoucherDetail()
        {
            VoucherDetail result = new VoucherDetail
            {
                Account = Account.Clone() as Account,
                AccountID = AccountID,
                CreateDate = DateTime.Now,
                Credit = Credit,
                Debit = Debit,
                Description = Description
            };

            return result;
        }

        public VoucherDetail ToUnpostVoucherDetail()
        {
            VoucherDetail result = new VoucherDetail
            {
                Account = Account.Clone() as Account,
                AccountID = AccountID,
                CreateDate = DateTime.Now,
                Credit = Debit,
                Debit = Credit,
                Description = "فك ترحيل, " + Description
            };

            return result;
        }
        #endregion
    }
}